﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using BGSpaceShooterServer;
using Microsoft.Xna.Framework;

namespace BGSpaceShooter
{
    /// <summary>
    /// Zawiera informacje o aktualnym stanie obiektu przesyłane z serwera do klienta
    /// </summary>
    public struct ServerStatusResponse 
    {
        public int playerId;
        /// <summary>
        /// Wykorzystywane jako unia
        /// </summary>
        private int unionField1;
        /// <summary>
        /// Wykorzystywane jako unia
        /// </summary>
        private int unionField2;

        /// <summary>
        /// Nie używac z ComponentIndex
        /// </summary>
        public GameObjectType gameObjectType
        {
            get
            {
                return (GameObjectType) unionField1;
            }
            set
            {
                unionField1 = (int) value;
            }
        }

        /// <summary>
        /// Nie używać z HPValue
        /// </summary>
        public GameObjectName GameObjectName
        {
            get
            {
                return (GameObjectName)unionField2;
            }
            set
            {
                unionField2 = (int)value;
            }
        }

        /// <summary>
        /// Nie używać z gameObjectType
        /// </summary>
        public int ComponentIndex
        {
            get
            {
                return unionField1;
            }
            set
            {
                unionField1 = value;
            }
        }

        /// <summary>
        /// Nie używać z GameObjectName
        /// </summary>
        public int HPValue
        {
            get
            {
                return unionField2;
            }
            set
            {
                unionField2 = value;
            }
        }

        public Vector3 Position;
        public Matrix Rotation;
        public Vector3 Velocity;

        /// <summary>
        /// Data wysłania wiadomości
        /// </summary>
        public DateTime TimeStamp;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]
        public string Message;
        
        public void SetTimeStamp(DateTime dateTime)
        {
            TimeStamp = dateTime;
        }

        private int engines;

        /// <summary>
        /// Aktualnie pracujące silniki
        /// </summary>
        public List<EngineName> Engines
        {
            get
            {
                List<EngineName> workingEngines = new List<EngineName>();
                for (int i=0; i < sizeof(int)*8; i++)
                {
                    int temp = engines >> i;
                    if ((temp & 1) == 1)
                    {
                        EngineName name; 
                        switch (i)
                        {
                            case 0:
                                name = EngineName.Main;
                                break;
                            case 1:
                                name = EngineName.leftZ;
                                break;
                            case 2:
                                name = EngineName.rightZ;
                                break;
                            case 3:
                                name = EngineName.topX;
                                break;
                            case 4:
                                name = EngineName.bottomX;
                                break;
                            default:
                                name = EngineName.none;
                                break;
                        }
                        workingEngines.Add(name);
                        
                    }
                }
                return workingEngines;
            }

            set
            {
                int result = 0; 
                foreach (EngineName name in value)
                {
                    switch (name)
                    {
                        case EngineName.Main:
                            result |= 1;
                            break;
                        case EngineName.leftZ:
                            result |= 2;
                            break;
                        case EngineName.rightZ:
                            result |= 4;
                            break;
                        case EngineName.topX:
                            result |= 8;
                            break;
                        case EngineName.bottomX:
                            result |= 16;
                            break;
                    }
                }
                engines = result;
            }
        
        }
    }
}
